package handlers

import (
	"ai-collections/pkg/models"
	"ai-collections/pkg/services"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
)

// TokenRequest 表示生成令牌的请求
type TokenRequest struct {
	CarID       string `json:"carId" binding:"required"`
	ChannelType string `json:"channelType" binding:"required"`
	ActiveTab   string `json:"activeTab"`
}

// ValidateTokenRequest 验证token的请求格式
type ValidateTokenRequest struct {
	Token string `json:"usertoken" binding:"required"`
	Carid string `json:"carid" binding:"required"`
}

// TokenResponse 验证token的响应格式
type TokenResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
}

// CreateTokenRequest 创建token的请求格式
type CreateTokenRequest struct {
	CarID       string `json:"carId"`
	ChannelType string `json:"channelType"`
	UserID      string `json:"userId,omitempty"`
}

// CreateTokenResponse 创建token的响应格式
type CreateTokenResponse struct {
	Token     string `json:"token"`
	ExpiresIn int64  `json:"expires_in"` // 过期时间(秒)
	Error     string `json:"error,omitempty"`
}

// ValidateTokenHandler 处理token验证请求
func ValidateTokenHandler(c *gin.Context) {
	//从url参数获取usertoken和carid
	usertoken := c.Query("usertoken")
	//如果usertoken为空，从form表单获取usertoken
	if usertoken == "" {
		usertoken = c.PostForm("usertoken")
	}
	//如果usertoken为空，从请求体json获取usertoken
	if usertoken == "" {
		var req ValidateTokenRequest
		if err := c.ShouldBindJSON(&req); err != nil {
			c.JSON(http.StatusBadRequest, TokenResponse{
				Code: 0,
				Msg:  "Invalid json format",
			})
			return
		}
		usertoken = req.Token
	}
	//如果usertoken为空，则返回错误
	if usertoken == "" {
		c.JSON(http.StatusBadRequest, TokenResponse{
			Code: 0,
			Msg:  "usertoken is required",
		})
		return
	}

	// 获取Redis token服务
	tokenService, err := services.GetRedisTokenService()
	if err != nil {
		log.Printf("Error getting token service: %v", err)
		c.JSON(http.StatusInternalServerError, TokenResponse{
			Code: 0,
			Msg:  "Token service unavailable",
		})
		return
	}

	// 验证并消费token（一次性使用）
	valid, _, err := tokenService.ValidateAndConsumeToken(usertoken)
	if err != nil {
		log.Printf("Token validation error: %v", err)
		c.JSON(http.StatusUnauthorized, TokenResponse{
			Code: 0,
			Msg:  err.Error(),
		})
		return
	}

	response := TokenResponse{}

	if valid {
		response.Code = 1
		response.Msg = "success"
	} else {
		response.Code = 0
		response.Msg = "用户不存在或身份已过期"
	}

	// 返回JSON响应
	if !valid {
		c.JSON(http.StatusUnauthorized, response)
	} else {
		c.JSON(http.StatusOK, response)
	}
}

// CreateTokenHandler 处理创建令牌的请求
func CreateTokenHandler(c *gin.Context) {
	var req TokenRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "Invalid request",
		})
		return
	}

	// 从请求头获取用户信息
	encryptedHeader := c.GetHeader("X-User-Info")
	var userInfo *models.DownstreamUserInfo
	var err error

	if encryptedHeader != "" {
		userInfo, err = models.DecryptUserInfo(encryptedHeader, encryptionKey)
		if err != nil || userInfo.UserID == "" {
			//解密失败 响应未登录错误
			c.JSON(http.StatusUnauthorized, gin.H{
				"error": "您尚未登录，请先登录",
			})
			return
		}
	} else {
		//encryptedHeader 为空 响应未登录错误
		c.JSON(http.StatusUnauthorized, gin.H{
			"error": "您尚未登录，请先登录",
		})
		return
	}

	// 获取Redis token服务
	tokenService, err := services.GetRedisTokenService()
	if err != nil {
		log.Printf("Error getting token service: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": "Token service unavailable",
		})
		return
	}

	// 创建token（3分钟有效期、一次性使用）
	token, err := tokenService.CreateToken(req.CarID, req.ChannelType, userInfo.UserID)
	if err != nil {
		log.Printf("Error creating token: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": "Failed to create token",
		})
		return
	}

	// 保存用户激活的页签信息到cookie
	if req.ActiveTab != "" {
		// 设置cookie，有效期7天
		c.SetCookie(
			"ai_collections_active_tab", // cookie名称
			req.ActiveTab,               // 存储激活的页签
			60*60*24*7,                  // 有效期7天
			"/",                         // 路径
			"",                          // 域名
			false,                       // 是否只在HTTPS上发送
			false,                       // 非HttpOnly，允许JavaScript访问
		)
		log.Printf("Saved active tab '%s' to cookie for user", req.ActiveTab)
	}

	// 返回令牌
	c.JSON(http.StatusOK, gin.H{
		"token": token,
	})
}
